package com.xjscrm.console.chat.core.impl.conversation;

import cn.hutool.core.util.IdUtil;
import com.xjscrm.common.entity.WwCustomer;
import com.xjscrm.common.entity.WwDevice;
import com.xjscrm.common.enums.ChatConversationTypeEnum;
import com.xjscrm.common.exception.BusinessException;
import com.xjscrm.console.chat.cache.CacheHolder;
import com.xjscrm.console.chat.core.ChatBaseMsgHandler;
import com.xjscrm.console.chat.enums.ChatMsgType;
import com.xjscrm.console.chat.frame.recv.RPullNewConversationMsg;
import com.xjscrm.console.chat.frame.send.SResultMsg;
import com.xjscrm.console.chat.utils.MessageUtil;
import com.xjscrm.console.entity.ChatTalkRecord;
import com.xjscrm.console.entity.ChatTalkSession;
import com.xjscrm.console.entity.ChatTalkSessionStaffRel;
import com.xjscrm.console.service.customer.chat.ChatTalkRecordService;
import com.xjscrm.console.service.customer.chat.ChatTalkSessionService;
import com.xjscrm.console.service.customer.chat.ChatTalkSessionStaffRelService;
import com.xjscrm.console.service.customer.merchat.MerchatChildDeviceRelationService;
import com.xjscrm.console.service.customer.wwCustomer.WwCustomerService;
import com.xjscrm.console.service.customer.wwDevice.WwDeviceService;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * @author mingyang.chen create in 2024/3/17 09:42
 */
@Component
@Slf4j
public class ChatPullNewConversationMsgHandler extends ChatBaseMsgHandler<RPullNewConversationMsg> {

    @Autowired
    private WwDeviceService wwDeviceService;

    @Autowired
    private CacheHolder cacheHolder;

    @Autowired
    private ChatTalkSessionService chatTalkSessionService;

    @Autowired
    private ChatTalkRecordService chatTalkRecordService;

    @Autowired
    private ChatTalkSessionStaffRelService chatTalkSessionStaffRelService;
    @Autowired
    private MerchatChildDeviceRelationService merchatChildDeviceRelationService;

    @Autowired
    private WwCustomerService wwCustomerService;

    @Override
    public Class<RPullNewConversationMsg> msgClass() {
        return RPullNewConversationMsg.class;
    }

    @Override
    public boolean checkMsg(RPullNewConversationMsg baseMsg) {
        return super.checkMsg(baseMsg) || !ObjectUtils.isNotEmpty(baseMsg.getWxId()) || !StringUtils.isNotBlank(baseMsg.getConversationName()) || !Objects.nonNull(baseMsg.getDeviceUniqueId());
    }

    @Override
    @Transactional
    public SResultMsg doHandle(RPullNewConversationMsg content, ChannelHandlerContext ctx) {

        Long merId = content.getMerId();
        Long staffId = content.getStaffId();
        Long deviceUniqueId = content.getDeviceUniqueId();
        String wxId = content.getWxId();

        WwDevice device = wwDeviceService.getById(merId, deviceUniqueId);
        if (Objects.isNull(device)) {
            throw new BusinessException("群聊创建失败: 设备未找到");
        }
        List<Long> deviceStaffs = merchatChildDeviceRelationService.listStaffIdsByDeviceUniqueId(merId, deviceUniqueId);
        if (!deviceStaffs.contains(staffId)) {
            throw new BusinessException("聊天创建失败, 此机器人未关联当前员工");
        }
        //
        Integer staffSessionNowCount = cacheHolder.getStaffSessionNowCount(merId, staffId);
        Integer staffSessionCount = cacheHolder.getStaffSessionCount(merId, staffId);
        if (staffSessionNowCount >= staffSessionCount) {
            throw new BusinessException("聊天创建失败, 已超出最大聊天数量限制");
        }

        //
        ChatTalkSession existsTalkSession = chatTalkSessionService.getByConvIdAndDeviceUniqueId(merId, deviceUniqueId, wxId);

        if (Objects.isNull(existsTalkSession)) {

            existsTalkSession = new ChatTalkSession();

            WwCustomer customer = wwCustomerService.getByWxId(merId, deviceUniqueId, wxId);
            if (Objects.nonNull(customer)) {
                existsTalkSession.setType(ChatConversationTypeEnum.prv_conversation.getCode());
                existsTalkSession.setConversationAvatar(customer.getHeadImgUrl());
            } else {
                existsTalkSession.setType(ChatConversationTypeEnum.group_conversation.getCode());
            }
            existsTalkSession.setId(IdUtil.getSnowflakeNextId());
            existsTalkSession.setMerId(merId);
            existsTalkSession.setDeviceUniqueId(deviceUniqueId);
            existsTalkSession.setDeviceId(device.getDeviceId());
            existsTalkSession.setDeviceType(device.getDeviceType());
            existsTalkSession.setConversationName(content.getConversationName());
            existsTalkSession.setConversationId(content.getWxId());

            existsTalkSession.setCreateTime((int) (System.currentTimeMillis() / 1000L));
            existsTalkSession.setUpdateTime((int) (System.currentTimeMillis() / 1000L));
            //
            chatTalkSessionService.add(existsTalkSession);
        } else {
            //
            ChatTalkSessionStaffRel sessionStaffRel = chatTalkSessionStaffRelService.getByConvIdAndSessionId(merId, wxId, existsTalkSession.getId());
            if (Objects.nonNull(sessionStaffRel) && !Objects.equals(sessionStaffRel.getStaffId(), staffId)) {
                throw new BusinessException("当前聊天已分发到其他员工, 请重新选择");
            }
        }
        //
        chatTalkSessionStaffRelService.addIfAbsent(merId, existsTalkSession, staffId);
        Long lastRecvId = existsTalkSession.getLastRecvId();

        ChatTalkRecord chatTalkRecord = null;
        if (Objects.nonNull(lastRecvId)) {
            chatTalkRecord = chatTalkRecordService.getById(merId, lastRecvId);
        }

        MessageUtil.sendNewSessionTalk(ctx.channel(), existsTalkSession, chatTalkRecord);
        return SResultMsg.success(content, "聊天创建成功");
    }

    @Override
    public ChatMsgType msgType() {
        return ChatMsgType.r_pull_new_conversation;
    }
}
